﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Configuration;
using System.Web.Security;

namespace wz.common
{
    /// <summary>
    /// 通用MD5加密对象
    /// </summary>
    public class MD5Signer
    {
        /// <summary>
        /// 验证签名
        /// </summary>
        /// <returns></returns>
        public static bool Validate(string url,string key)
        {
            Uri uri = new Uri(url);
            NameValueCollection nvCol = HttpUtility.ParseQueryString(uri.Query);

            if (nvCol["timestamp"] == null || nvCol["sign"] == null)
            {
                return false;
            }

            //验证时间有效性 5分钟内有效
            var timestamp = new UnixTimeStamp(nvCol["timestamp"]);
            TimeSpan ts = timestamp.GetTimeDiff();
            if (ts> new TimeSpan(0, 5, 0))
            {
                return false;
            }

            string sign=GeneSign(key, nvCol);
            bool pass = sign.ToLower() == nvCol["sign"].ToLower();
            if (!pass)
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// 生成Sign字段
        /// </summary>
        /// <param name="key"></param>
        /// <param name="nvCol"></param>
        /// <returns></returns>
        private static string GeneSign(string key, NameValueCollection nvCol)
        {
            Dictionary<string, string> dic = new Dictionary<string, string>();
            foreach (string item in nvCol.Keys)
            {
                if (item.ToLower() != "sign")
                {
                    dic.Add(item, HttpUtility.UrlDecode(nvCol[item]));
                }
            }

            var sortdic = dic.OrderBy(c => c.Key);

            var s = new StringBuilder();
            foreach (var d in sortdic)
            {
                s.Append("&" + d.Key + "=" + d.Value);
            }
            s.Remove(0, 1);
            string sign = FormsAuthentication.HashPasswordForStoringInConfigFile(s.ToString().ToLower() + key, "MD5");
            return sign;
        }



        /// <summary>
        /// 原始地址加签名
        /// </summary>
        /// <param name="originUrl"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string AddSign(string originUrl,string key)
        {
            Uri uri = new Uri(originUrl);
            string path = "http://" + uri.Host + uri.LocalPath;
            NameValueCollection nvCol = HttpUtility.ParseQueryString(uri.Query);
            if (nvCol["timestamp"] != null)
            {
                nvCol.Remove("timestamp");
            }
            if ( nvCol["sign"] == null)
            {
                nvCol.Remove("sign");
            }

            nvCol.Add("timestamp", UnixTimeStamp.Now.ToString());
            string sign = GeneSign(key, nvCol);
            nvCol.Add("sign", sign);
            string temp = string.Empty;
            foreach (string item in nvCol)
            {
                temp += item + "=" + nvCol[item] + "&";
            }
            return path + "?" + temp;
        }

    }
}